package com.chixing.service.impl;

import com.chixing.entity.DTO.MessageDTO;
import com.chixing.entity.Message;
import com.chixing.entity.OrderTransactions;
import com.chixing.entity.Orders;
import com.chixing.entity.UserMessage;
import com.chixing.entity.VO.OrderVO;
import com.chixing.mapper.MessageMapper;
import com.chixing.mapper.OrderTransactionsMapper;
import com.chixing.mapper.OrdersMapper;
import com.chixing.mapper.UserMessageMapper;
import com.chixing.service.IOrderTransactionsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chixing.service.IOrdersService;
import com.chixing.utils.Result;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author smith
 * @since 2025-09-30
 */
@Service
public class OrderTransactionsServiceImpl implements IOrderTransactionsService {

    @Autowired
    private OrderTransactionsMapper orderTransactionsMapper;
    @Autowired
    private IOrdersService iOrdersService;
    @Autowired
    private  OrdersMapper ordersMapper;
    @Autowired
    private UserMessageMapper userMessageMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //支付  添加流水  修改订单状态
    @Override
    public Result save(OrderTransactions orderTransactions) {

        orderTransactions.setTransactionsNo(UUID.randomUUID().toString().replace("-",""));
        orderTransactions.setCreatedAt(LocalDateTime.now());
        orderTransactions.setTransactionsStatus("已支付");

        //1.添加流水
        int rows = orderTransactionsMapper.insert(orderTransactions);

        if(rows > 0){
            System.out.println("支付成功，支付记录是："+ orderTransactions );
            // 根据completedType判断是否修改订单状态
            // 只有普通支付时才修改为“待入住”，延迟退房支付不修改订单状态
            if (!"延迟退房支付".equals(orderTransactions.getCompletedType())) {
                //2.修改订单状态
                Result updateOrderResult  = iOrdersService.updateStatus(orderTransactions.getOrderId(), "待入住");

                if(updateOrderResult.getCode() == 200){
                    System.out.println("修改订单状态成功---------order id = " + orderTransactions.getOrderId());
                    Result myorderResult = iOrdersService.getById(orderTransactions.getOrderId());

                    Orders myorder = (Orders) myorderResult.getData();

                    System.out.println("正在生成支付成功的消息");
                    //作为生产者要将消息保存到数据库，并传到MQ
                    //因为没有userId所以要从流水表中查出订单id，在通过订单id查询到userId
                    Long orderId = orderTransactions.getOrderId();
                    Orders orders = ordersMapper.selectById(orderId);
                    Long userId = orders.getUserId();
                    //从message表中查询出要发送的信息
                    Message message = messageMapper.selectById(2);//酒店预定成功的消息
                    //把信息存到数据库
                    UserMessage userMessage = new UserMessage();
                    userMessage.setMessageId(message.getMessageId());
                    userMessage.setUserId(userId);
                    userMessage.setStatus("UNREAD");
                    userMessage.setIsPushed(0);
                    userMessage.setCreatedAt(LocalDateTime.now());
                    userMessage.setOrderId(orderId);
                    userMessageMapper.insert(userMessage);
                    //把消息封装成messageDTO对象，发送到MQ
                    MessageDTO messageDTO = new MessageDTO();
                    messageDTO.setId(userMessage.getId());
                    messageDTO.setUserId(userId);
                    messageDTO.setOrderNumber(orders.getOrderNumber());
                    messageDTO.setTitle(message.getTitle());
                    messageDTO.setContent(message.getContent());
                    messageDTO.setType(message.getType());
                    messageDTO.setSendTime(LocalDateTime.now());
                    // 先创建CorrelationData，携带userMessage的ID作为唯一标识
                    CorrelationData correlationData = new CorrelationData(userMessage.getId().toString());
                    rabbitTemplate.convertAndSend("order.exchange","order.payment",messageDTO,correlationData);
                    System.out.println("支付成功的消息已发送到mq");
                    return Result.getSuccess(orderTransactions);
                }
            }else {
                // 延迟退房支付，不修改订单状态，直接返回成功
                System.out.println("正在生成延迟退房支付成功的消息");
                //作为生产者要将消息保存到数据库，并传到MQ
                //因为没有userId所以要从流水表中查出订单id，在通过订单id查询到userId
                Long orderId = orderTransactions.getOrderId();
                Orders orders = ordersMapper.selectById(orderId);
                Long userId = orders.getUserId();
                //从message表中查询出要发送的信息
                Message message = messageMapper.selectById(4);//订单延迟退房成功的消息
                //把信息存到数据库
                UserMessage userMessage = new UserMessage();
                userMessage.setMessageId(message.getMessageId());
                userMessage.setUserId(userId);
                userMessage.setStatus("UNREAD");
                userMessage.setIsPushed(0);
                userMessage.setCreatedAt(LocalDateTime.now());
                userMessage.setOrderId(orderId);
                userMessageMapper.insert(userMessage);
                //把消息封装成messageDTO对象，发送到MQ
                MessageDTO messageDTO = new MessageDTO();
                messageDTO.setId(userMessage.getId());
                messageDTO.setUserId(userId);
                messageDTO.setOrderNumber(orders.getOrderNumber());
                messageDTO.setTitle(message.getTitle());
                messageDTO.setContent(message.getContent());
                messageDTO.setType(message.getType());
                messageDTO.setSendTime(LocalDateTime.now());
                // 先创建CorrelationData，携带userMessage的ID作为唯一标识
                CorrelationData correlationData = new CorrelationData(userMessage.getId().toString());
                rabbitTemplate.convertAndSend("order.exchange","order.delay.payment",messageDTO,correlationData);
                System.out.println("支付成功的消息已发送到延迟退房mq");
                return Result.getSuccess(orderTransactions);
            }

        }
        return Result.getFail("支付失败");
    }

    @Override
    public Result getOrderDetailsById(Long orderId) {
        OrderVO orderVOByOrderId = orderTransactionsMapper.getOrderVOByOrderId(orderId);

        if(orderVOByOrderId != null)
            return Result.getSuccess(orderVOByOrderId);

        return Result.getFail(null);
    }

    @Override
    public Result getOrderDetailsByNumber(String orderNumber) {
        OrderVO orderVOByOrderId = orderTransactionsMapper.getOrderVOByOrderNumber(orderNumber);

        if(orderVOByOrderId != null)
            return Result.getSuccess(orderVOByOrderId);

        return Result.getFail(null);
    }

//    @Override
//    public Result getOrderAllByTransactionsId(Long orderTransactionsId) {
//        OrderVO orderAllVOByTransactionsId = orderTransactionsMapper.getOrderAllVOByTransactionsId(orderTransactionsId);
//
//        if(orderAllVOByTransactionsId != null)
//            return Result.getSuccess(orderAllVOByTransactionsId);
//
//        return Result.getFail(null);
//    }
    @Override
    public Result getOrderAllByTransactionsId(Long orderTransactionsId) {
        Map<Object,Object> map = new HashMap<>();
        OrderVO orderAllVOByTransactionsId = orderTransactionsMapper.getOrderAllVOByTransactionsId(orderTransactionsId);
        map.put("transactionsNo",orderAllVOByTransactionsId.getTransactionsNo());
        map.put("transactionCreatedAt",orderAllVOByTransactionsId.getTransactionCreatedAt());
        map.put("amount",orderAllVOByTransactionsId.getAmount());
        Orders orders = ordersMapper.selectById(orderAllVOByTransactionsId.getOrderId());
        map.put("orderNumber",orders.getOrderNumber());
        map.put("orderCreatedAt",orders.getCreatedAt());

        if(map != null)
            return Result.getSuccess(map);

        return Result.getFail(null);
    }
}
